package com.employment.service.impl;

import com.employment.dao.JobApplicationMapper;
import com.employment.dao.JobPositionMapper;
import com.employment.entity.JobApplication;
import com.employment.service.JobApplicationService;
import com.mybatisflex.core.paginate.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 求职申请服务实现类
 * 
 * @author Employment System
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class JobApplicationServiceImpl implements JobApplicationService {

    private final JobApplicationMapper jobApplicationMapper;
    private final JobPositionMapper jobPositionMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean applyJob(JobApplication jobApplication) {
        try {
            // 检查是否已经申请过该职位
            JobApplication existingApplication = jobApplicationMapper.selectByUserAndJob(
                    jobApplication.getUserId(), jobApplication.getJobId());
            if (existingApplication != null) {
                throw new RuntimeException("您已申请过该职位，请勿重复申请");
            }
            
            // 设置默认状态
            jobApplication.setStatus(1); // 1-待查看
            
            boolean success = jobApplicationMapper.insert(jobApplication) > 0;
            
            // 增加职位申请次数
            if (success) {
                jobPositionMapper.increaseApplyCount(jobApplication.getJobId());
            }
            
            return success;
        } catch (Exception e) {
            log.error("申请职位失败: ", e);
            throw new RuntimeException("申请职位失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean withdrawApplication(Long applicationId, Long userId) {
        try {
            JobApplication application = jobApplicationMapper.selectOneById(applicationId);
            if (application == null) {
                throw new RuntimeException("申请记录不存在");
            }
            
            if (!application.getUserId().equals(userId)) {
                throw new RuntimeException("无权限操作该申请");
            }
            
            // 只有待查看和已查看状态的申请才能撤回
            if (application.getStatus() != 1 && application.getStatus() != 2) {
                throw new RuntimeException("当前状态的申请无法撤回");
            }
            
            application.setStatus(7); // 7-已撤回
            return jobApplicationMapper.update(application) > 0;
        } catch (Exception e) {
            log.error("撤回申请失败: ", e);
            throw new RuntimeException("撤回申请失败: " + e.getMessage());
        }
    }

    @Override
    public JobApplication getApplicationById(Long applicationId) {
        return jobApplicationMapper.selectOneById(applicationId);
    }

    @Override
    public Page<JobApplication> getUserApplicationPage(Page<JobApplication> page,
                                                       Long userId,
                                                       Integer status) {
        return jobApplicationMapper.selectUserApplicationPage(page, userId, status);
    }

    @Override
    public Page<JobApplication> getCompanyApplicationPage(Page<JobApplication> page,
                                                         Long companyId,
                                                         Long jobId,
                                                         Integer status) {
        return jobApplicationMapper.selectCompanyApplicationPage(page, companyId, jobId, status);
    }

    @Override
    public boolean hasApplied(Long userId, Long jobId) {
        JobApplication application = jobApplicationMapper.selectByUserAndJob(userId, jobId);
        return application != null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean viewApplication(Long applicationId, Long viewedBy) {
        try {
            JobApplication application = jobApplicationMapper.selectOneById(applicationId);
            if (application == null) {
                throw new RuntimeException("申请记录不存在");
            }
            
            // 更新查看状态和时间
            if (application.getStatus() == 1) { // 待查看状态
                application.setStatus(2); // 2-已查看
            }
            application.setViewTime(LocalDateTime.now());
            application.setViewedBy(viewedBy);
            
            return jobApplicationMapper.update(application) > 0;
        } catch (Exception e) {
            log.error("查看申请失败: ", e);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean replyApplication(Long applicationId, String replyContent, Integer status, Long operatorId) {
        try {
            JobApplication application = jobApplicationMapper.selectOneById(applicationId);
            if (application == null) {
                throw new RuntimeException("申请记录不存在");
            }
            
            application.setReplyContent(replyContent);
            application.setReplyTime(LocalDateTime.now());
            application.setStatus(status);
            application.setViewedBy(operatorId);
            
            return jobApplicationMapper.update(application) > 0;
        } catch (Exception e) {
            log.error("回复申请失败: ", e);
            throw new RuntimeException("回复申请失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean sendInterviewInvitation(JobApplication jobApplication, Long operatorId) {
        try {
            JobApplication application = jobApplicationMapper.selectOneById(jobApplication.getApplicationId());
            if (application == null) {
                throw new RuntimeException("申请记录不存在");
            }
            
            // 更新面试相关信息
            application.setStatus(3); // 3-面试邀请
            application.setInterviewTime(jobApplication.getInterviewTime());
            application.setInterviewAddress(jobApplication.getInterviewAddress());
            application.setInterviewContact(jobApplication.getInterviewContact());
            application.setInterviewPhone(jobApplication.getInterviewPhone());
            application.setInterviewNote(jobApplication.getInterviewNote());
            application.setReplyTime(LocalDateTime.now());
            application.setViewedBy(operatorId);
            
            return jobApplicationMapper.update(application) > 0;
        } catch (Exception e) {
            log.error("发送面试邀请失败: ", e);
            throw new RuntimeException("发送面试邀请失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean rejectApplication(Long applicationId, String rejectReason, Long operatorId) {
        try {
            JobApplication application = jobApplicationMapper.selectOneById(applicationId);
            if (application == null) {
                throw new RuntimeException("申请记录不存在");
            }
            
            application.setStatus(6); // 6-已拒绝
            application.setRejectReason(rejectReason);
            application.setReplyTime(LocalDateTime.now());
            application.setViewedBy(operatorId);
            
            return jobApplicationMapper.update(application) > 0;
        } catch (Exception e) {
            log.error("拒绝申请失败: ", e);
            throw new RuntimeException("拒绝申请失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean hireApplicant(Long applicationId, Long operatorId) {
        try {
            JobApplication application = jobApplicationMapper.selectOneById(applicationId);
            if (application == null) {
                throw new RuntimeException("申请记录不存在");
            }
            
            application.setStatus(5); // 5-已录用
            application.setReplyTime(LocalDateTime.now());
            application.setViewedBy(operatorId);
            
            return jobApplicationMapper.update(application) > 0;
        } catch (Exception e) {
            log.error("录用申请者失败: ", e);
            throw new RuntimeException("录用申请者失败");
        }
    }

    @Override
    public List<String> getUserApplicationStats(Long userId) {
        return jobApplicationMapper.selectUserApplicationStats(userId);
    }

    @Override
    public List<String> getCompanyApplicationStats(Long companyId) {
        return jobApplicationMapper.selectCompanyApplicationStats(companyId);
    }

    @Override
    public Integer getPendingApplicationCount(Long companyId) {
        return jobApplicationMapper.countPendingApplications(companyId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateStatus(List<Long> applicationIds, Integer status, Long operatorId) {
        try {
            return jobApplicationMapper.batchUpdateStatus(applicationIds, status, operatorId) > 0;
        } catch (Exception e) {
            log.error("批量更新申请状态失败: ", e);
            throw new RuntimeException("批量更新申请状态失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteApplications(List<Long> applicationIds, Long operatorId) {
        try {
            // 软删除
            for (Long applicationId : applicationIds) {
                jobApplicationMapper.deleteById(applicationId);
            }
            return true;
        } catch (Exception e) {
            log.error("批量删除申请失败: ", e);
            throw new RuntimeException("批量删除申请失败");
        }
    }
}